﻿using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace VideoWriter
{
    public class AudioSource:IDisposable
    {
        /// <summary>
        /// 获取到Pcm数据
        /// </summary>
        public event Action<byte[]> OnGetPcmData;

        #region 音频源
        /// <summary>
        /// 音频源对象
        /// </summary>
        private WaveInEvent audioSource;

        /// <summary>
        /// 支持的音频格式
        /// </summary>
        private SupportedWaveFormat audioWaveFormat;

        #endregion

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="timeSpan">PCM音频数据包采集帧率</param>
        public AudioSource(int fps)
        {
            //用户选择了有效的音频设备
            audioWaveFormat = SupportedWaveFormat.WAVE_FORMAT_44M16;
            WaveFormat waveFormat = ToWaveFormat(audioWaveFormat);

            audioSource = new WaveInEvent
            {
                DeviceNumber = 0,
                WaveFormat = waveFormat,
                // Buffer size to store duration of 1 frame
                BufferMilliseconds = (int)Math.Ceiling(1000.0 / fps),
                NumberOfBuffers = 3,
            };

            if (audioSource != null)
            {
                try
                {
                    audioSource.DataAvailable += audioSource_DataAvailable;
                    audioSource.StartRecording();
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.StackTrace);
                    audioSource = null;
                }
            }
        }

        #region 音频相关

        /// <summary>
        /// 音频源数据回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void audioSource_DataAvailable(object sender, WaveInEventArgs e)
        {
            Trace.TraceInformation($"Data Count {e.BytesRecorded}");
            OnGetPcmData?.Invoke(e.Buffer);
        }

        /// <summary>
        /// 支持的音频格式选择
        /// </summary>
        /// <param name="waveFormat"></param>
        /// <returns></returns>
        private static WaveFormat ToWaveFormat(SupportedWaveFormat waveFormat)
        {
            switch (waveFormat)
            {
                case SupportedWaveFormat.WAVE_FORMAT_44M16:
                    return new WaveFormat(44100, 16, 1);
                case SupportedWaveFormat.WAVE_FORMAT_44S16:
                    return new WaveFormat(44100, 16, 2);
                default:
                    throw new NotSupportedException("Wave formats other than '16-bit 44.1kHz' are not currently supported.");
            }
        }

        public void Dispose()
        {
            if (audioSource != null)
            {
                audioSource.StopRecording();
                audioSource.DataAvailable -= audioSource_DataAvailable;
            }
        }

        #endregion
    }
}
